package net.shambolica.ember.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.commons.lang.StringUtils.isEmpty;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.util.*;

/**
 * Utilities for fetching PIDs and otherwise accessing the Java Runtime.
 */
public class RuntimeUtils {

    public static final Logger log = LoggerFactory.getLogger(RuntimeUtils.class);

    public static long getPid() {
        String pname = ManagementFactory.getRuntimeMXBean().getName();
        log.debug("got process name = '{}'", pname);
        String myPid = pname.split("@")[0];
        log.debug("pid = '{}'", myPid);
        long ret = Long.parseLong(myPid);
        log.debug("numeric pid = {}", ret);
        return ret;
    }


    public static String createNodeName(String prefix, String postfix) {
        long pid = getPid();
        return (isEmpty(prefix) ? "" : prefix+"-") +
                pid +
                (isEmpty(postfix) ? "" : "-"+postfix);
    }


    public static List<String> getValidRelativeEmberPaths() {
        return Arrays.asList(
                "ember",        // E.g. under 'classes'.
                "../ember"      // E.g. under 'WEB-INF', when in web container.
        );
    }


    public static List<String> getEmberPaths() {
        List<String> relativePaths = getValidRelativeEmberPaths();
        TreeSet<String> ret = new TreeSet<String>();
        try {
            for (Enumeration<URL> it = RuntimeUtils.class.getClassLoader().getResources("") ; it.hasMoreElements() ; ) {
                URL url = it.nextElement();
                String base = url.getPath();
                if (! isEmpty(base)) {
                    for (String relative : relativePaths) {
                        try {
                            File dir = new File(base + "/" + relative);
                            String path = dir.getCanonicalPath();
                            if (!dir.isDirectory()) {
                                log.debug("path '{}' not a directory", path);
                            } else {
                                log.debug("adding '{}' to ember base paths", path);
                                ret.add(path);
                            }
                        } catch (IOException e) {
                            log.warn("io exception while getting canonical path of '{}' for base path", base);
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("failed getting ember lib paths", e);
            throw new RuntimeException(e.getMessage(), e);
        }
        return new ArrayList<String>(ret);
    }


    public static List<String> getEmberLibPaths() {
        List<String> basePaths = getEmberPaths();
        List<String> ret = new ArrayList<String>();
        for (String base: basePaths) {
            try {
                File dir = new File(base+"/lib");
                String path = dir.getCanonicalPath();
                if (! dir.isDirectory()) {
                    log.debug("lib path '{}' not a directory", path);
                } else {
                    log.debug("adding '{}' to ember lib paths");
                    ret.add(path);
                }
            } catch (IOException e) {
                log.warn("io exception while getting lib path of '{}' for lib path", base);
            }
        }
        return ret;
    }

}
